//
// 作者：AKA_GGbond
// 时间：2025/7/17
// 邮箱：evain_wl@163.com
//

#include "W_Slider.h"
#include <QPainter>
#include <QPainterPath>
#include <QMouseEvent>
#include <QFontMetrics>
#include <QLinearGradient>
#include <QDebug>

W_Slider::W_Slider(QWidget* parent)
    : QAbstractSlider(parent)
{
    this->resize(392, 20);

    initUISetting();
    initValue();
    setWindowFlags(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);
}

W_Slider::~W_Slider()
{
}

void W_Slider::setRange(qreal nMin, qreal nMax)
{
    if (nMax < nMin)
    {
        nMax = nMin;
    }

    m_range.m_nMin = nMin;
    m_range.m_nMax = nMax;

    updateValue(0);
}

void W_Slider::slotSetValue(qreal nValue)
{
    updateValue(nValue);
}

qreal W_Slider::value() const
{
    return m_nCurValue;
}

void W_Slider::setFillValueColor(const QColor& color)
{
    if (m_currentValueColor == color)
    {
        return;
    }

    m_currentValueColor = color;
    update();
}

void W_Slider::setUnfillValueColor(const QColor& color)
{
    if (color == m_invalidValueColor)
    {
        return;
    }
    m_invalidValueColor = color;
    update();
}

void W_Slider::setValueTextColor(const QColor& color)
{
    m_valueTextColor = color;
    update();
}

void W_Slider::paintEvent(QPaintEvent* event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.setBrush(Qt::NoBrush);

    QSizeF currentValueSize{ 50, height()*1.0 };

    // 绘制 Slider 轨道
    QRectF sliderRect(m_dbRadius, height() / 2 - 5, width() - m_dbRadius* 2 - currentValueSize.width(), m_dbRadius);

    {
        // Slider 轨道的尺寸
        qreal trackHeight = m_dbRadius;
        qreal cornerRadius = trackHeight / 2;
        QRectF sliderRectAA(m_dbRadius, (height() - trackHeight) / 2, sliderRect.width(), trackHeight);

        // 绘制未划过的区域（灰色）
        QPainterPath trackPath;
        trackPath.addRoundedRect(sliderRect, cornerRadius, cornerRadius);
        painter.setPen(Qt::NoPen);
        painter.setBrush(QBrush(m_invalidValueColor));
        painter.drawPath(trackPath);

        // 绘制划过的区域（绿色）
        QPainterPath filledPath{};

        qreal sliderWidth = sliderRect.width() * m_dbCurPercent;
        QRectF knobRect(sliderRect.x(), sliderRect.y(), sliderWidth, trackHeight);

        filledPath.addRoundedRect(knobRect, m_dbRadius / 2, m_dbRadius / 2);
        painter.setBrush(m_currentValueColor);
        painter.drawPath(filledPath);

    }

    qreal sliderWidth = sliderRect.width() * 1.0;
    // 绘制滑块
    qreal x = sliderRect.x() + sliderWidth * m_dbCurPercent;
    QRectF knobRect(x - m_dbRadius, sliderRect.center().y() - m_dbRadius, 2 * m_dbRadius, 2 * m_dbRadius);

    painter.setBrush(m_currentValueColor);
    painter.setPen(Qt::NoPen);
    // 绘制圆形滑块
    painter.drawEllipse(knobRect);

    painter.setPen(m_valueTextColor);
    painter.setBrush(Qt::NoBrush);
    QFont ft = painter.font();
    ft.setPointSizeF(10.0);
    painter.setFont(ft);
    QRectF currentValueRect(QPointF(sliderRect.x() + m_dbRadius + sliderRect.width(), 0), currentValueSize);
    painter.drawText(currentValueRect, Qt::AlignLeft | Qt::AlignVCenter, QString::number(m_nCurValue, 'f', 1));
}

void W_Slider::mouseMoveEvent(QMouseEvent* event)
{
    if (m_bPressed)
    {
        QSizeF currentValueSize{ 50, height() * 1.0 };

        // 绘制 Slider 轨道
        QRectF sliderRect(m_dbRadius, height() / 2 - 5, width() - m_dbRadius * 2 - currentValueSize.width(), m_dbRadius);
        QPoint pressPoint = event->pos();

        if (true == sliderRect.contains(pressPoint))
        {
            m_dbCurPercent = ((event->pos().x() - sliderRect.x()) * 1.0) / sliderRect.width();
            m_nCurValue = (m_range.m_nMax - m_range.m_nMin) * m_dbCurPercent;
            update();
            emit sigValueChanged(m_nCurValue);

        }
            /// 在外面
        else
        {
            int pressXX = pressPoint.x();

            /// 移动到最右侧
            if (pressXX > (sliderRect.width() + sliderRect.x()))
            {
                m_dbCurPercent = 1.0;
                m_nCurValue = (m_range.m_nMax - m_range.m_nMin) * m_dbCurPercent;
                emit sigValueChanged(m_nCurValue);
                update();
            }
            else if (pressXX < sliderRect.x())
            {
                m_dbCurPercent = 0.0;
                m_nCurValue = (m_range.m_nMax - m_range.m_nMin) * m_dbCurPercent;
                update();
                emit sigValueChanged(m_nCurValue);
            }
            else
            {
                m_dbCurPercent = ((event->pos().x() - sliderRect.x()) * 1.0) / sliderRect.width();
                m_nCurValue = (m_range.m_nMax - m_range.m_nMin) * m_dbCurPercent;
                update();
                emit sigValueChanged(m_nCurValue);
            }
        }
    }

    QWidget::mouseMoveEvent(event);
}

void W_Slider::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)
    {
        /// 如果是鼠标左键单击
        if (QEvent::MouseButtonPress == event->type())
        {
            QSizeF currentValueSize{ 50, height() * 1.0 };

            // 绘制 Slider 轨道
            QRectF sliderRect(m_dbRadius, height() / 2 - 5, width() - m_dbRadius * 2 - currentValueSize.width(), m_dbRadius);
            QPoint pressPoint = event->pos();

            QRectF checkSliderRect(sliderRect);
            checkSliderRect.setX(sliderRect.x() - m_dbRadius);
            checkSliderRect.setY(sliderRect.y() - m_dbRadius);
            checkSliderRect.setWidth(sliderRect.width() + m_dbRadius * 2);
            checkSliderRect.setHeight(sliderRect.height() + m_dbRadius * 2);

            if (true == checkSliderRect.contains(pressPoint))
            {
                qreal tmpXX = pressPoint.x() * 1.0;
                if (false == sliderRect.contains(pressPoint))
                {
                    if (tmpXX > (sliderRect.x() + sliderRect.width()))
                    {
                        tmpXX = (sliderRect.x() + sliderRect.width() ) * 1.0;
                    }
                    else if (tmpXX < sliderRect.x())
                    {
                        tmpXX = sliderRect.x() * 1.0;
                    }
                    else
                    {

                    }
                }

                m_bPressed = true;
                m_dbCurPercent = (tmpXX - sliderRect.x() * 1.0) / sliderRect.width();
                m_nCurValue = (m_range.m_nMax - m_range.m_nMin) * m_dbCurPercent;
                emit sigValueChanged(m_nCurValue);
                update();
            }
        }
    }
}

void W_Slider::mouseReleaseEvent(QMouseEvent* event)
{
    if (m_bPressed)
    {
        m_bPressed = false;
    }

    QWidget::mouseReleaseEvent(event);
}

void W_Slider::updateValue(qreal nCurValue)
{
    if (m_nCurValue == nCurValue)
    {
        return;
    }
    m_nCurValue = nCurValue;
    if (m_range.m_nMax == m_range.m_nMin)
        m_dbCurPercent = 0;
    else
        m_dbCurPercent = m_nCurValue * 1.0 / (m_range.m_nMax - m_range.m_nMin);
    update();
}

void W_Slider::initValue()
{
    m_range = { 0, 100 };
    m_nCurValue = 0;
    m_dbCurPercent = 0;
    m_bPressed = false;
}

void W_Slider::initUISetting()
{
    //setCursor(QCursor(Qt::PointingHandCursor));
    setMouseTracking(true);
    setFocusPolicy(Qt::StrongFocus);
}
